home *** CD-ROM | disk | FTP | other *** search
/ isnet Internet / Isnet Internet CD.iso / prog / hiz / 09 / 09.exe / adynware.exe / perl / lib / adynware / web_gen.pm < prev    next >
Encoding:
Text File  |  2000-04-09  |  20.9 KB  |  633 lines

  1. use strict;
  2. #use diagnostics;
  3. package web_gen;
  4. use adynware::utility_file;
  5. use IO::File;
  6. use adynware::web_site;
  7.  
  8. my %w__anchors = ();
  9. my %w__chunks = ();
  10. my @w__fileNames = ();
  11.  
  12.  
  13. my $web_gen__indexIsGenerated = 0;
  14. my $web_gen__linkmenuIsGenerated = 0;
  15. my $web_gen__inForm = 0; 
  16. my %web_gen__variables = ();
  17.  
  18. sub Init
  19. {
  20.         if (! -f "index.htm")
  21.         {
  22.                 my $file = new IO::File("> index.htm") or die "cannot create index.htm\n"; 
  23.                 $web_gen__indexIsGenerated = 1;
  24.                 my $indexContent =<<'EOS';
  25. <head>
  26. <title>@@siteTitle</title>
  27. </head>
  28. <html>
  29. <frameset rows="150,*">
  30. <frame name="header"  src="etc/header.html" scrolling="no" marginwidth="0" marginheight="0">
  31. <frameset rows="100%" cols="30%, 70%,*">
  32. <frame name="toc_frame"  src="etc/linkmenu.html" scrolling="no" marginwidth="0" marginheight="0">
  33. <frame name="content_frame" src="etc/home.html" scrolling="auto" marginwidth="0" marginheight="0">
  34. </frameset>
  35. </frameset>
  36. </html>
  37. EOS
  38.         print $file $indexContent;
  39.         $file->close();
  40.         }
  41. }
  42.  
  43. sub Cleanup
  44. {
  45.         unlink("index.htm") if $web_gen__indexIsGenerated;
  46.         unlink("etc/linkmenu.htm") if $web_gen__linkmenuIsGenerated;
  47. }
  48.  
  49. sub LinkMenu
  50. {
  51.         my($color_1, $color_2, $itemsReference) = @_;
  52.         #die "tmp file etc/linkmenu.htm already exists" if (-f "etc/linkmenu.htm");
  53.         $web_gen__linkmenuIsGenerated = 1;
  54.         my $file = new IO::File("> etc/linkmenu.htm") or die "cannot create etc/linkmenu.htm\n"; 
  55.         my $linkMenuStart =<<'EOS';
  56.         <html>
  57.         <head>
  58.         <base target="content_frame">
  59.         </head>
  60.         <body bgcolor=black link=white vlink=white text=white>
  61. EOS
  62.         print $file $linkMenuStart;
  63.         web_gen::Colored_table2($file, "100%", undef, 1, 25, $color_1, $color_2, $itemsReference);
  64.                                 
  65.         print $file "</body></html>";
  66.         $file->close();
  67. }
  68.  
  69.  
  70. sub SetVariables
  71. {
  72.         my($fileSpecification, $key, $value) = @_;
  73.         if (defined $fileSpecification)
  74.         {
  75.                 $web_gen__variables{$fileSpecification, $key} = $value;
  76.                 #print "web_gen__variables{$fileSpecification, $key} = $value;\n";
  77.         }
  78.         else
  79.         {
  80.                 $web_gen__variables{$key} = $value;
  81.                 #print "web_gen__variables{$key} = $value;\n";
  82.         } 
  83. }
  84.  
  85. sub GetVariable
  86. {
  87.         my($directory, $key, $mustResolve, $default) = @_;
  88.         my $value;
  89.         return $web_gen__variables{$directory, $key} if (defined $web_gen__variables{$directory, $key});
  90.         return $web_gen__variables{$key} if (defined $web_gen__variables{$key});
  91.         die "GetVariable($directory, $key): did not see anything" if $mustResolve;
  92.         return $default;
  93. }
  94.  
  95. sub InterpolateVariables
  96. {
  97.         my($fileName, $data) = @_;
  98.         $data = InterpolateVariables_2($fileName, $data, 0);
  99.         $fileName =~ m{(.*)/} or die "interpolate variables: cannot get directory out of $fileName";
  100.         my $directory = $1;
  101.         $data = InterpolateVariables_2($directory, $data, 1);
  102.         return $data;
  103. }
  104. sub InterpolateVariables_2
  105. {
  106.         my($fileSpecification, $data, $mustResolve) = @_;
  107.         $data =~ s/(\@\@([a-zA-Z]?\w*[a-zA-Z0-9])\{(.*?)\})/GetVariable($2, $3, $mustResolve, $1)/eg;
  108.         $data =~ s/(\@\@([a-zA-Z]?\w*[a-zA-Z0-9]))/GetVariable($fileSpecification, $2, $mustResolve, $1)/eg;
  109.         $data =~ s/(\@\@\{([a-zA-Z]?\w*[a-zA-Z0-9])\})/GetVariable($fileSpecification, $2, $mustResolve, $1)/eg;
  110.         return $data;
  111. }
  112.  
  113.  
  114. sub SiteHeader
  115. {
  116.         my($fileName, $title, $subtitle, $textReference, $color_1, $color_2) = @_;
  117.         web_gen::SetVariables(undef, "siteTitle", $title);
  118.         my @text = @$textReference;
  119.                                                 
  120.         my $file = new IO::File("> $fileName") or die "cannot open $fileName\n";
  121.                         
  122.         print $file "<html>\n";
  123.         print $file "<header>\n";
  124.         print $file "<title>$title</title>\n";
  125.         print $file "</header>\n";
  126.         print $file "<body bgcolor=black link=white vlink=white text=white>\n";
  127.                 
  128.         unshift(@text, ["<font size=7>$title</font><font size=5>$subtitle</font>"]);
  129.                 
  130.         Colored_table2($file, "100%", undef, 0, 0, $color_1, $color_2, \@text);
  131.         $file->close();
  132.  
  133.  
  134. sub Link
  135. {
  136.         my($linkText, $linkDestination) = @_;
  137.                 
  138.         if ($linkDestination =~ m{[ :/]})
  139.         {
  140.                 return "<a href=$linkDestination>" . $linkText . "</a>";
  141.         }
  142.         return "<!--link $linkDestination " . $linkText . "-->";
  143. }
  144.  
  145. sub FormBegin
  146. {
  147.         my($name) = @_;
  148.         $web_gen__inForm = 1;
  149.         return "<form name=$name>\n";
  150. }
  151. sub FormEnd
  152. {
  153.         $web_gen__inForm = 0;
  154.         return "</form>\n";
  155. }
  156.  
  157. sub Button
  158. {
  159.         my($name, $label, $attributes) = @_;
  160.         my $begin = "";
  161.         my $end = "";
  162.         if (!$web_gen__inForm)
  163.         {
  164.                 $begin = FormBegin("form_" . $name);
  165.                 $end = FormEnd();
  166.         }
  167.  
  168.         return "$begin <input type=button value='$label' name=$name $attributes> $end";
  169. }
  170.  
  171. sub Select
  172. {
  173.         my($fieldName, $attributes, $displaySize, $valueArrayReference, $labelArrayReference) = @_;
  174.         my $field = "<select name=$fieldName size=$displaySize $attributes";
  175.         $field .= ">\n";
  176.                 
  177.         my @valueArray = (); @valueArray = @$valueArrayReference if defined $valueArrayReference;
  178.         my @labelArray = (); @labelArray = @$labelArrayReference if defined $labelArrayReference;
  179.         
  180.         die "web_gen::Select: mismatched value and label arrays" unless scalar(@valueArray)==scalar(@labelArray);
  181.                 
  182.         for (my $j = 0; $j < scalar(@valueArray); $j++)
  183.         {
  184.                 $field .= "<option ";
  185.                 $field .= "selected " unless $j;
  186.                 $field .= "value='$valueArray[$j]'>$labelArray[$j]\n";
  187.         }
  188.         $field .= "</select>\n";
  189.         return $field;
  190. }
  191.  
  192. sub Radio
  193. {
  194.         my($fieldName, $valueArrayReference, $labelArrayReference, $selectedValue, $attributes) = @_;
  195.         my $field = "";
  196.                 
  197.         my @valueArray = (); @valueArray = @$valueArrayReference if defined $valueArrayReference;
  198.         my @labelArray = (); @labelArray = @$labelArrayReference if defined $labelArrayReference;
  199.         
  200.         die "web_gen::Radio: mismatched value and label arrays" unless scalar(@valueArray)==scalar(@labelArray);
  201.                 
  202.         for (my $j = 0; $j < scalar(@valueArray); $j++)
  203.         {
  204.                 $field .= "<input type=radio name=$fieldName ";
  205.                 $field .= "checked " if ($valueArray[$j] eq $selectedValue);
  206.                 $field .= "$attributes value='$valueArray[$j]'>$labelArray[$j]<br>\n";
  207.         }
  208.         return $field;
  209. }
  210.  
  211.  
  212. sub CheckBox
  213. {
  214.         my($fieldName, $value, $checked, $label, $attributes) = @_;
  215.         my $field = "<input type=checkbox name=$fieldName value='$value'";
  216.         if ($checked)
  217.         {
  218.                 $field .= " checked";
  219.         }
  220.         $field .= " $attributes>$label\n";
  221.         return $field;
  222. }
  223.  
  224. sub TextField
  225. {
  226.         my($fieldName, $displayLength, $attributes) = @_;
  227.         return "<input type=text name=$fieldName size=$displayLength $attributes>";
  228. }
  229.  
  230. sub Colored_table
  231. {
  232.         my($fileName, $width, $formName, $cellspacing, $rowCount, $colorStart, $colorEnd, $rowsReference) = @_;
  233.                         
  234.         my $file = new IO::File("> $fileName") or die "cannot open $fileName\n";
  235.                                 
  236.         Index_preamble($file);
  237.         print $file "<body bgcolor=black link=white vlink=white text=white>\n";
  238.         
  239.         Colored_table2($file, $width, $formName, $cellspacing, $rowCount, $colorStart, $colorEnd, $rowsReference);
  240.         $file->close();
  241. }
  242.  
  243. sub Colored_table2
  244. {
  245.         my($file, $width, $formName, $cellspacing, $rowCount, $colorStart, $colorEnd, $rowsReference) = @_;
  246.                                                         
  247.         (length($colorStart)==6) || die "$colorStart parameter is not a 6-digit hex number";
  248.         (length($colorEnd  )==6) || die "$colorEnd   parameter is not a 6-digit hex number";
  249.                 
  250.         my   $redStart = hex(substr($colorStart, 0, 2));
  251.         my $greenStart = hex(substr($colorStart, 2, 2));
  252.         my  $blueStart = hex(substr($colorStart, 4, 2));
  253.                 
  254.         my   $redEnd = hex(substr($colorEnd, 0, 2));
  255.         my $greenEnd = hex(substr($colorEnd, 2, 2));
  256.         my  $blueEnd = hex(substr($colorEnd, 4, 2));
  257.                 
  258.         my @rows = @$rowsReference;
  259.         $rowCount = scalar(@rows) unless $rowCount; 
  260.         
  261.         print $file "<form name=$formName>\n" if $formName;
  262.         print $file "<table bgcolor=black width=$width cellpadding=0 cellspacing=$cellspacing border=0>\n";
  263.                                 
  264.         my $red = $redStart;
  265.         my $redIncrement = int(($redEnd - $redStart)/$rowCount);
  266.         my $green = $greenStart;
  267.         my $greenIncrement = int(($greenEnd - $greenStart)/$rowCount);
  268.         my $blue = $blueStart;
  269.         my $blueIncrement = int(($blueEnd - $blueStart)/$rowCount);
  270.         
  271.         my $firstRowReference = $rows[0];
  272.         my $columnCount = scalar(@$firstRowReference);
  273.                                 
  274.         for (my $row = 0; $row < $rowCount; $row++)
  275.         {
  276.                 my $color = sprintf("%0.2x%0.2x%0.2x", $red, $green, $blue);
  277.                                                                                         
  278.                 print $file "<tr>\n";
  279.                 if ($row < scalar(@rows))
  280.                 {
  281.                         my $rowReference = $rows[$row];
  282.                         my @columns;
  283.                         if (defined $rowReference)
  284.                         {
  285.                                 @columns = @$rowReference;
  286.                         }
  287.                         else
  288.                         {
  289.                                 @columns = ( undef );
  290.                         }
  291.                         
  292.                         for (my $column = 0; $column < $columnCount; $column++)
  293.                         {
  294.                                 my $text = $columns[$column];
  295.                                 $text = " " unless defined $text;
  296.                                 
  297.                                 print $file "<td bgcolor=#$color> $text</td>\n";
  298.                         }
  299.                 }
  300.                 else
  301.                 {
  302.                         for (my $column = 0; $column < $columnCount; $column++)
  303.                         {
  304.                                 print $file "<td bgcolor=#$color> </td>\n";
  305.                         }
  306.                 }
  307.                 print $file "</tr>\n";
  308.                 $red += $redIncrement;
  309.                 $green += $greenIncrement;
  310.                 $blue += $blueIncrement;
  311.         }
  312.         print $file "</table>\n";
  313.         print $file "</form>\n" if $formName;
  314. }
  315.  
  316. sub DocumentBegin
  317. {
  318.         my($title, $fileName) = @_;
  319.         my $anchorName = $fileName;
  320.         $anchorName =~ s|/|_|g;
  321.         $anchorName =~ s/\.[^\.]*//;
  322.         
  323.         return "<html>
  324.         <head>
  325.         <title>$title</title>
  326.         </head>
  327.         <body bgcolor=#cccce2>
  328.         <!--anchor file_" . $anchorName . "-->
  329.         ";                
  330. }
  331. sub DocumentEnd
  332. {
  333.         return "\n<!--include copyright-->\n</body>\n</html>";
  334. }
  335.  
  336. sub ReadFAQElement
  337. {
  338.         my($input) = @_;
  339.         my $element = <$input>;
  340.         return 0 unless $element;
  341.         $element =~ s/^(.)/\U$1/;    # capitalize
  342.         while (<$input>)
  343.         {
  344.                 last unless ($_ and ($_ ne "\n"));
  345.                 $element .= $_;
  346.         }
  347.         $element =~ s/\s*$//;        # trim trailing white
  348.         return $element;
  349. }
  350.  
  351. sub GenerateFAQ
  352. {
  353.         my($inFileName) = @_;
  354.         #print "GenerateFAQ $inFileName\n";
  355.         die "bad FAQ file name (expected '.faq' suffix)" unless $inFileName =~ /(.*)\.FAQ/i;
  356.         my $outFileName = "$1.htm";
  357.         
  358.         my  $input = new IO::File("<  $inFileName") or die "could not open $inFileName";
  359.         my $output = new IO::File("> $outFileName") or die "could not open $outFileName";
  360.  
  361.         print $output DocumentBegin("\@\@product FAQ", $outFileName);
  362.         print $output "<h1>\@\@product FAQ</h1>";
  363.  
  364.         my @questions = ();
  365.         my @answers = ();
  366.         for (my $j = 1;; $j++)
  367.         {
  368.                 my $question = ReadFAQElement($input);
  369.                 last unless $question;
  370.                 $questions[$j-1] = $question;
  371.                 $answers[$j-1] = ReadFAQElement($input);
  372.         }
  373.         $input->close();
  374.                                 
  375.         for (my $j = 1; $j <= scalar(@questions); $j++)
  376.         {
  377.                 print $output "<p><a href=#$j>", $j, ". $questions[$j-1]?</a>\n";
  378.         }
  379.         for (my $j = 1; $j <= scalar(@questions); $j++)
  380.         {
  381.                 print $output "<h3><a name=$j>", $j, ". $questions[$j-1]?</a></h3>\n";
  382.                 print $output $answers[$j-1];
  383.         }
  384.  
  385.         print $output DocumentEnd();
  386.         $output->close();
  387. }
  388.  
  389. sub Gather_input_document_list
  390. {
  391.         my($suffix, @directories) = @_;
  392.         push(@directories, ".");
  393.         
  394.         @w__fileNames = ();
  395.         foreach my $directory (@directories)
  396.         {
  397.                 opendir(DIR, $directory) or die "cannot open directory $directory:$!";
  398.                 foreach my $file (readdir(DIR))
  399.                 {
  400.                         if ($file =~ /\.$suffix$/)
  401.                         {
  402.                                 push(@w__fileNames, "$directory/$file");
  403.                         }
  404.                 }
  405.                 closedir(DIR);
  406.         }
  407. }
  408.  
  409. sub GenerateFAQs
  410. {
  411.         my(@directories) = @_;
  412.         Gather_input_document_list("faq", @directories);
  413.         foreach my $fileName (@w__fileNames)
  414.         {
  415.                 GenerateFAQ($fileName);
  416.         }
  417. }
  418.  
  419.  
  420. sub Gather_chunks_in_string
  421. {
  422.         my($rawContent, $fileName) = @_;
  423.         #print "Gather_chunksin string($rawContent, $fileName) \n";
  424.         while ($rawContent =~ /(<!--chunk ([@\w]+)-->(.*?)<!--chunkEnd \2-->)/gs)
  425.         {
  426.                 my $chunkContentIncludingTags = $1;
  427.                 my $chunkName = $2;
  428.                 my $chunkContent = $3;
  429.                                                 
  430.                 #print "saw chunk $chunkName in $fileName\n";
  431.                 defined $w__chunks{$chunkName} and die "chunk $chunkName multiply defined";
  432.                 $chunkContentIncludingTags =~ s/(<!--anchor) /$1: copy /g;
  433.                 
  434.                 $w__chunks{ $chunkName} = $chunkContentIncludingTags; 
  435.                 Gather_chunks_in_string($chunkContent, $fileName);
  436.         }
  437. }
  438.  
  439. sub Gather_chunks
  440. {
  441.         foreach my $fileName (@w__fileNames)                
  442.         { 
  443.                 my $rawContent = utility_file::getContent("$fileName");
  444.                 Gather_chunks_in_string($rawContent, $fileName);
  445.         }
  446. }
  447.  
  448. sub Gather_links2
  449. {
  450.         my($copies) = @_;
  451.         foreach my $inputFileName (@w__fileNames) 
  452.         { 
  453.                 my $fileName = $inputFileName . "l";
  454.                 my $rawContent = utility_file::getContent("$fileName");
  455.                 while ($rawContent =~ /<!--anchor$copies ([@\w]+)-->/g)
  456.                 {
  457.                         if (defined $w__anchors{$1})
  458.                         {
  459.                                 if ($copies)
  460.                                 {
  461.                                         #print "ignored copied anchor $1 in $fileName\n";
  462.                                 }
  463.                                 else
  464.                                 {
  465.                                         die "anchor $1 multiply defined in $fileName";
  466.                                 }
  467.                         }
  468.                         else
  469.                         {
  470.                                 #print "anchor $1 in $fileName\n";
  471.                                 $w__anchors{$1} = "$fileName" . "#$1";
  472.                         }
  473.                 }
  474.         }
  475. }
  476.  
  477. sub Gather_links
  478. {
  479.         Gather_links2("");
  480.         Gather_links2(": copy");
  481. }
  482.  
  483.  
  484. sub AccessHash
  485. {
  486.         my($hashElementName, $key, $hashReference, $fileName) = @_;
  487.         my $value = $$hashReference{$key};
  488.         die "!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n!\n$key is not a defined $hashElementName in $fileName" unless defined $value;
  489.         return $value;
  490. }
  491.  
  492. sub ResolveLink
  493. {
  494.         my($fileName, $logicalLinkName, $hashReference) = @_;
  495.         my $link = AccessHash("anchor", $logicalLinkName, $hashReference, $fileName);
  496.                                                 
  497.         my $offset = "";
  498.         $offset = $1 if $link =~ s/(#.*)//;
  499.                                 
  500.         $offset = "" if $offset =~ /^#file_/;
  501.                         
  502.                 
  503.         my $resolvedLink;
  504.         if ($link eq $fileName)
  505.         {
  506.                 $resolvedLink = $offset; 
  507.         }
  508.         else
  509.         {
  510.                 my $level = utility_file::directoryDepth($fileName);
  511.                 $resolvedLink = "";
  512.                 for (my $j = 0; $j < $level; $j++)
  513.                 {
  514.                         $resolvedLink .= "../";
  515.                 }
  516.                 $resolvedLink .= $link;
  517.                 $resolvedLink .= $offset;
  518.         }
  519.         return $resolvedLink;
  520. }
  521.  
  522. sub EvaluateIf
  523. {
  524.         my($expression, $data, $fileName) = @_;
  525.         #print STDERR "about to evaluate '$expression' in EvaluateIf in $fileName\n";
  526.         my $value = eval($expression);
  527.         if ($@)
  528.         {
  529.                 print STDERR "error evaluating '$expression' in EvaluateIf in $fileName\n";
  530.                 return "";
  531.         }
  532.         return $data if $value;
  533.         return "";
  534. }
  535.  
  536. sub Resolve_chunks_in_string
  537. {
  538.         my($content, $fileName) = @_;
  539.         $content =~ s/(<!--include ([@\w]+)-->)/$1 . Resolve_chunks_in_string(AccessHash("chunk", $2, \%w__chunks, $fileName), $fileName)/ge;
  540.         return $content;
  541. }
  542.  
  543. sub Resolve_chunks
  544. {
  545.         foreach my $inputFileName (@w__fileNames)                
  546.         { 
  547.                 my $rawContent = utility_file::getContent("$inputFileName");
  548.                 my $fileName = $inputFileName . "l";
  549.                 utility_file::setContent($fileName, Resolve_chunks_in_string($rawContent, $fileName));
  550.         }
  551. }
  552.  
  553.  
  554. sub Resolve_links_and_includes
  555. {
  556.         Gather_chunks();
  557.         Resolve_chunks();
  558.         foreach my $inputFileName (@w__fileNames)                
  559.         {
  560.         #print "c:/perl/lib/adynware/web_gen.pm Resolve_links_and_includes($inputFileName)\n";
  561.         
  562.                 my $fileName = $inputFileName . "l";
  563.                 my $content = utility_file::getContent("$fileName");
  564.                                                 
  565.                 $content = InterpolateVariables($fileName, $content); 
  566.                 $content =~ s/(<!--if +(.*?)-->.*?<!--endif \2-->)/EvaluateIf($2, $1, $fileName)/egms;
  567.                 
  568.                 utility_file::setContent($fileName, $content);
  569.         }
  570.         Gather_links();
  571.         foreach my $inputFileName (@w__fileNames)                
  572.         {
  573.                 my $fileName = $inputFileName . "l";
  574.                 my $content = utility_file::getContent("$fileName");
  575.                                                                 
  576.                 $content =~ s{(<!--anchor(: copy)? (\w+)-->)}{$1<a name=$3></a>}g;
  577.                 $content =~ s{(<!--link +(\w+) (.*?)-->)}{"$1<a href=" . ResolveLink($fileName, $2, \%w__anchors) . ">$3</a>"}egms;
  578.                                                 
  579.                 utility_file::setContent($fileName, $content);
  580.         }
  581. }
  582.  
  583. sub Strip_comments
  584. {
  585.         foreach my $inputFileName (@w__fileNames)                
  586.         {
  587.                 my $fileName = $inputFileName . "l";
  588.                 my $content = utility_file::getContent("$fileName");
  589.                 $content =~ s/<!--.*?-->//gs;
  590.                 utility_file::setContent($fileName, $content);
  591.         }
  592. }
  593.  
  594.  
  595.  
  596. sub Get_links_to_be_verified
  597. {
  598.         my %linksToBeVerified = ();
  599.         foreach my $inputFileName (@w__fileNames)                
  600.         {
  601.                 my $fileName = $inputFileName . "l";
  602.                 my $content = utility_file::getContent("$fileName");
  603.                                                                 
  604.                 while ($content =~ m{(-->)?<a href=['"]?([^'"\s>]*)}gms)
  605.                 {
  606.                         next if $1;
  607.                         my $link = $2;
  608.                         next if $link =~ /^#\d+$/;  # next if this is a generated faq link we can trust
  609.                         $link = web_site::makeAbsolute($link, $fileName);
  610.                         next if $link !~ m{^https?://}; # we only check http, https
  611.                         print "verify links: saw $link in $fileName\n";
  612.                         $linksToBeVerified{$link} = 1;
  613.                 }
  614.         }
  615.         return [keys %linksToBeVerified];
  616. }
  617.  
  618. sub web_gen__variable_get
  619. {
  620.         my($fileSpecification, $variable) = @_;
  621.         my $value = $web_gen__variables{$fileSpecification, $variable};
  622.         return $value if defined $value;
  623.                 
  624.         
  625.         $fileSpecification =~ m{(.*)/} or die "web_gen__variable_get: cannot get directory out of $fileSpecification";
  626.         my $directory = $1;
  627.         $value = $web_gen__variables{$directory, $variable};
  628.         return $value if defined $value;
  629.         return 0;
  630. }
  631. 1;
  632.